/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2005
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
* 
* Author's email :    insane@dees.ufmg.br
* Author's website :  http://www.dees.ufmg.br/insane
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package br.ufmg.dees.insane.ui.rich.full.command;

import java.awt.geom.Point2D;
import java.util.ListIterator;

import javax.swing.JInternalFrame;

import br.ufmg.dees.insane.commons.command.Command;
import br.ufmg.dees.insane.model.geo.GCubicCurve;
import br.ufmg.dees.insane.model.geo.GLine;
import br.ufmg.dees.insane.model.geo.GPoint;
import br.ufmg.dees.insane.model.geo.GQuadCurve;
import br.ufmg.dees.insane.model.geo.GeometricModel;
import br.ufmg.dees.insane.prep.MapElement;
import br.ufmg.dees.insane.prep.MapNode;
import br.ufmg.dees.insane.prep.MappingModel;
import br.ufmg.dees.insane.ui.rich.full.InsaneInternalInterface;

/**
 *
 * @author Fonseca, Flavio & Pitangueira, Roque
 * @since March 2004
 */
public class MappingCommand implements Command {
    
    private InsaneInternalInterface parent;
	private MappingModel mmodel;
	private GeometricModel gmodel;
	
//*****************************************************************************
	
    /** Creates new MappingCommand */
    public MappingCommand(JInternalFrame parent) {
        this.parent = (InsaneInternalInterface)parent;
    }
    
//*****************************************************************************
	
	/** Execute method. */
	public void execute() {
		
		mmodel = parent.getModel().getMModel();
		mmodel.clear();
		
		gmodel = (GeometricModel)parent.getModel().getGModel();
		MapNode node;
		MapNode[] nds = new MapNode[2];
		MapElement elm;
		Point2D p;
		GLine gl;
		GQuadCurve gq;
		GCubicCurve gc;
		
		//Adding nodes to FemModel
		ListIterator pts = gmodel.getPoints().listIterator();
		while (pts.hasNext()){
			p = (Point2D)pts.next();
			node = new MapNode(p.getX(), p.getY());
			mmodel.add(node);
		}
		
		//Adding nodes and elements from lines partition to FemModel
		ListIterator lns = gmodel.getLines().listIterator();
		while (lns.hasNext()) {
			gl = (GLine)lns.next();
			int nParts = gl.getNParts();
			GPoint[] disc;
			disc = gl.getDiscrete();
			for (int count = 1; count < nParts; count++) {
				node = new MapNode(disc[count].getX(), disc[count].getY());
				mmodel.add(node);
			}
			for (int count = 0; count < nParts; count++) {
				nds[0] = mmodel.getMapNode(disc[count].getX(), disc[count].getY());
				nds[1] = mmodel.getMapNode(disc[count+1].getX(), disc[count+1].getY());
				elm = new MapElement(nds);
				elm.setType('F', 'F');
				mmodel.add(elm);
			}
		}
		
		//Adding nodes and elements from cubics curves partition to FemModel
		ListIterator cbs = gmodel.getCubics().listIterator();
		while(cbs.hasNext()) {
			gc = (GCubicCurve)cbs.next();
			int nParts = gc.getNParts();
			GPoint[] disc;
			disc = gc.getDiscrete();
			for (int count = 1; count < nParts; count++) {
				node = new MapNode(disc[count].getX(), disc[count].getY());
				mmodel.add(node);
			}
			for (int count = 0; count < nParts; count++) {
				nds[0] = mmodel.getMapNode(disc[count].getX(), disc[count].getY());
				nds[1] = mmodel.getMapNode(disc[count+1].getX(), disc[count+1].getY());
				elm = new MapElement(nds);
				elm.setType('F', 'F');
				mmodel.add(elm);
			}
		}
		
		//Adding nodes and elements from quadratic curves partition to FemModel
		ListIterator qcs = gmodel.getQuads().listIterator();
		while(qcs.hasNext()) {
			gq = (GQuadCurve)qcs.next();
			int nParts = gq.getNParts();
			GPoint[] disc;
			disc = gq.getDiscrete();
			for (int count = 1; count < nParts; count++) {
				node = new MapNode(disc[count].getX(), disc[count].getY());
				mmodel.add(node);
			}
			for (int count = 0; count < nParts; count++) {
				nds[0] = mmodel.getMapNode(disc[count].getX(), disc[count].getY());
				nds[1] = mmodel.getMapNode(disc[count+1].getX(), disc[count+1].getY());
				elm = new MapElement(nds);
				elm.setType('F', 'F');
				mmodel.add(elm);
			}
		}
		
		this.nameNodes();
		this.nameElements();
		
		parent.nothingToUndo();
		parent.nothingToRedo();
		
	}
    
//*****************************************************************************
	
    /**
     * Impossible to undo - not implemented.
     */
    public void undo() {}
    
//*****************************************************************************
	
    /**
     * Impossible to redo - not implemented.
     */
    public void redo() {}
    
//*****************************************************************************
	
	/** Sets the labels of the Nodes. */
	public void nameNodes() {
		
		ListIterator nodes = mmodel.getMapNodes().listIterator();
		MapNode node;
		int i = 0;
		int name;
		while (nodes.hasNext()) {
			node = (MapNode)nodes.next();
			i++;
			name = i;
			node.setLabel(name);
		}
		
	}
	
//*****************************************************************************
	
	/** Sets the labels of the Elements. */
	public void nameElements() {
		
		ListIterator elms = mmodel.getMapElements().listIterator();
		MapElement elm;
		MapNode[] nds;
		int name;
		while (elms.hasNext()) {
			elm = (MapElement)elms.next();
			nds = elm.getBoundary();
			name = nds[0].getLabel()*100 + nds[1].getLabel();
			elm.setLabel(name);
		}
		
	}
	
//*****************************************************************************
}
